import proj4 from 'proj4';
import CoordTransform from './CoordTransform'
export const coordConvert = {
    data() {
        return {}
    },
    mounted() {

// console.log("this.wgs84ToEcef(112.36789952,39.47235526,1348.8061)",this.wgs84ToEcef(39.47235526,112.36789952,1348.8061))
    },
    methods: {
        wgs84ToGcj02(longitude, latitude) {
            if(isNaN(longitude))return[longitude, latitude]
            return CoordTransform.WGS84ToGCJ02(longitude, latitude)
        },
        Gcj02ToWgs84(longitude, latitude) {
            if(isNaN(longitude))return[longitude, latitude]
            return CoordTransform.GCJ02ToWGS84(longitude, latitude)
        },
        wgs84ToCgcs2000(longitude, latitude) {
            if(isNaN(longitude))return[longitude, latitude]
            // 默认三度带计算
            let loncentre = lonCalculation(longitude, 3)
            // 定义 WGS84 和 CGCS2000 的投影信息
            proj4.defs("WGS84", "+proj=longlat +datum=WGS84 +no_defs");
            proj4.defs("CGCS2000", "+proj=tmerc +lat_0=0 +lon_0=" + loncentre.lon + " +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs");
            // 使用 proj4 进行坐标转换
            var wgs84Coord = [longitude, latitude];
            var cgcs2000Coord = proj4("WGS84", "CGCS2000", wgs84Coord);
            cgcs2000Coord.push(loncentre.num)
            return cgcs2000Coord
        },
        Cgcs2000ToWgs84(longitude, latitude, loncentre) {
            if(isNaN(longitude))return[longitude, latitude]
            // // 定义 WGS84 和 CGCS2000 的投影信息 
            proj4.defs("WGS84", "+proj=longlat +datum=WGS84 +no_defs");
            proj4.defs("CGCS2000", "+proj=tmerc +lat_0=0 +lon_0=" + loncentre + " +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs");
            // 使用 proj4 进行坐标转换
            var cgcs2000Coord = [longitude, latitude];
            var wgs84Coord = proj4("CGCS2000", "WGS84", cgcs2000Coord);
            return wgs84Coord
        },
        // wgs84 到 高斯投影
        wgs84ToPseudoMercator(longitude, latitude) {
            if(isNaN(longitude))return[longitude, latitude]
            // EPSG:4326  EPSG:3857
            proj4.defs("WGS84", "+proj=longlat +datum=WGS84 +no_defs");
            proj4.defs("PseudoMercator", "+proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs");
            // 使用 proj4 进行坐标转换
            var wgs84Coord = [longitude, latitude];
            var PseudoMercatorCoord = proj4("WGS84", "PseudoMercator", wgs84Coord);
            return PseudoMercatorCoord
        },
        // 高斯投影 到 wgs84
        PseudoMercatorToWgs84(longitude, latitude) {
            if(isNaN(longitude))return[longitude, latitude]
            // EPSG:4326  EPSG:3857
            proj4.defs("WGS84", "+proj=longlat +datum=WGS84 +no_defs");
            proj4.defs("PseudoMercator", "+proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs");
            // 使用 proj4 进行坐标转换
            var PseudoMercatorCoord = [longitude, latitude];
            var wgs84Coord = proj4("PseudoMercator", "WGS84", wgs84Coord);
            return wgs84Coord
        },
        // ecefToWgs84
        ecefToWgs84(x, y, z) {
            // WGS84 parameters
            const a = 6378137.0; // semi-major axis in meters
            const f = 1 / 298.257223563; // flattening
            const e2 = f * (2 - f); // eccentricity squared

            const lonRad = Math.atan2(y, x);

            // Calculate latitude using iterative method
            let latRad = Math.atan2(z, Math.sqrt(x * x + y * y));
            let N;
            do {
                const sinLat = Math.sin(latRad);
                N = a / Math.sqrt(1 - e2 * sinLat * sinLat);
                latRad = Math.atan2(z + N * e2 * sinLat, Math.sqrt(x * x + y * y));
            } while (Math.abs(latRad - Math.atan2(z, Math.sqrt(x * x + y * y))) > 1e-10);

            const altitude = Math.sqrt(x * x + y * y + z * z) - N;

            // Convert latitude and longitude from radians to degrees
            const latitude = (latRad * 180.0) / Math.PI;
            const longitude = (lonRad * 180.0) / Math.PI;

            return { latitude, longitude, altitude };
        },
        //   wgs84ToEcef
        wgs84ToEcef(longitude, latitude, altitude) {
            // WGS84 parameters
            const a = 6378137.0; // semi-major axis in meters
            const f = 1 / 298.257223563; // flattening

            const radianLat = (latitude * Math.PI) / 180.0;
            const radianLon = (longitude * Math.PI) / 180.0;

            // Calculate the geocentric latitude
            const tanLat = Math.tan(radianLat);
            const cf = 1.0 / Math.sqrt(1 + (1 - f) * (1 - f) * tanLat * tanLat);
            const sf = cf * (1 - f) * (1 - f);
            const ro = a * cf + altitude;

            // Calculate ECEF coordinates
            const x = ro * Math.cos(radianLat) * Math.cos(radianLon);
            const y = ro * Math.cos(radianLat) * Math.sin(radianLon);
            const z = ro * Math.sin(radianLat) * (1 - f) * (1 - f);

            return { x, y, z };
        }

    }
}

/**
 * 投影带的带号计算：通过用户输入的经纬度及定义的投影带宽度，得到该经纬度下投影带的带号
 * @param long  输入 用户输入的经度
 * @param projectedBandWidth  输入 用户定义的投影带宽度
 * @returns {number}  返回  经纬度下投影带的带号
 */
function bandNumberCalculation(long, projectedBandWidth) {
    var num;
    if (long <= 180) {
        if (projectedBandWidth === 6) {
            num = Math.floor(long / projectedBandWidth) + 1;
        } else if (projectedBandWidth === 3) {
            num = Math.floor((long - 1.5) / projectedBandWidth) + 1;
        } else {
            num = 0;
        }
    } else {
        num = extractBandNumber(long);
    }
    return num;
}

/**
 * 计算中央经线
 * @param {*} lon 输入 用户输入的经度
 * @param {*} projectedBandWidth  输入 用户定义的投影带宽度
 * @returns {lon}  返回 中央经线
 */
function lonCalculation(lon, projectedBandWidth) {
    var num = bandNumberCalculation(lon, projectedBandWidth);
    var lon;
    if (projectedBandWidth === 6) {
        lon = num * 6 - 3;
    } else if (projectedBandWidth === 3) {
        lon = num * 3;
    }
    return { lon, num };
}
